import 'dart:async';
import 'package:azlistview/azlistview.dart';
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
import 'package:get/get.dart';
import 'package:openim/routes/app_navigator.dart';
import 'package:openim_common/openim_common.dart';

import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
import 'package:get/get.dart';



import '../../home/home_logic.dart';
import '../../../core/controller/im_controller.dart';
import '../select_contacts/select_contacts_logic.dart';

class FriendListLogic extends GetxController {
  final imLoic = Get.find<IMController>();
  final friendList = <ISUserInfo>[].obs;
  final userIDList = <String>[];
  final openIM2DomainID = <String, String>{};
  late StreamSubscription delSub;
  late StreamSubscription addSub;
  late StreamSubscription infoChangedSub;

  final isSearching = false.obs;
  
  int _count = 10000;

  final homeLogic = Get.find<HomeLogic>();
  int get friendApplicationCount => homeLogic.unhandledFriendApplicationCount.value;

  int get groupApplicationCount => homeLogic.unhandledGroupApplicationCount.value;

  void newFriend() => AppNavigator.startFriendRequests();
  void newGroup() => AppNavigator.startGroupRequests();
  void myGroup() => AppNavigator.startGroupList();

  
  void search() => AppNavigator.startGlobalSearch(searchFriendOnly: true);

  @override
  void onInit() {
    delSub = imLoic.friendDelSubject.listen(_delFriend);
    addSub = imLoic.friendAddSubject.listen(_addFriend);
    infoChangedSub = imLoic.friendInfoChangedSubject.listen(_friendInfoChanged);
    imLoic.onBlacklistAdd = _delFriend;
    imLoic.onBlacklistDeleted = _addFriend;
    super.onInit();
  }

  @override
  void onReady() {
    getFriendList();
    super.onReady();
  }

  @override
  void onClose() {
    delSub.cancel();
    addSub.cancel();
    infoChangedSub.cancel();
    super.onClose();
  }

  getFriendList() async {
    List<FriendInfo> list = [];
    for (int i = 0;; i++) {
      final temp = await OpenIM.iMManager.friendshipManager.getFriendListPage(
        offset: list.length,
        count: _count,
        filterBlack: true,
      );
      list.addAll(temp);

      if (temp.length < _count) {
        break;
      }

      _count = 1000;
    }

    final result = list.map((e) {
      userIDList.add(e.userID!);
      return ISUserInfo.fromJson(e.toJson());
    }).toList();

    await Future.wait(result.map((info) async {
      final profile = await Apis.getUserProfileByOpenIMID(info.userID!);
      if (profile != null) {
        openIM2DomainID[info.userID!] = profile.userID ?? info.userID!;
        info.nickname = profile.nickname ?? info.nickname;
        info.faceURL = profile.faceURL ?? info.faceURL;
        info.gender = profile.gender ?? info.gender;
        info.birth = profile.birth ?? info.birth;
        info.email = profile.email ?? info.email;
        info.phoneNumber = profile.phoneNumber ?? info.phoneNumber;
        info.areaCode = profile.areaCode ?? info.areaCode;
        info.ex = profile.ex ?? info.ex;
      }
    }));

    final convertResult = IMUtils.convertToAZList(result);

    onUserIDList(userIDList);
    friendList.assignAll(convertResult.cast<ISUserInfo>());
  }

  void onUserIDList(List<String> userIDList) {}

  _addFriend(dynamic user) async {
    if (user is FriendInfo || user is BlacklistInfo) {
      await _addUser(user.toJson());
    }
  }

  _delFriend(dynamic user) {
    if (user is FriendInfo || user is BlacklistInfo) {
      friendList.removeWhere((e) => e.userID == user.userID);
      openIM2DomainID.remove(user.userID);
    }
  }

  _friendInfoChanged(FriendInfo user) async {
    friendList.removeWhere((e) => e.userID == user.userID);
    await _addUser(user.toJson());
  }

  Future<void> _addUser(Map<String, dynamic> json) async {
    final info = ISUserInfo.fromJson(json);
    final profile = await Apis.getUserProfileByOpenIMID(info.userID!);
    if (profile != null) {
      openIM2DomainID[info.userID!] = profile.userID ?? info.userID!;
      info.nickname = profile.nickname ?? info.nickname;
      info.faceURL = profile.faceURL ?? info.faceURL;
      info.gender = profile.gender ?? info.gender;
      info.birth = profile.birth ?? info.birth;
      info.email = profile.email ?? info.email;
      info.phoneNumber = profile.phoneNumber ?? info.phoneNumber;
      info.areaCode = profile.areaCode ?? info.areaCode;
      info.ex = profile.ex ?? info.ex;
    }
    friendList.add(IMUtils.setAzPinyinAndTag(info) as ISUserInfo);

    SuspensionUtil.sortListBySuspensionTag(friendList);

    SuspensionUtil.setShowSuspensionStatus(friendList);
  }

  void viewFriendInfo(ISUserInfo info) => AppNavigator.startUserProfilePane(
        userID: info.userID!,
        nickname: info.nickname,
        faceURL: info.faceURL,
      );
}
